package com.huo.deque;

import java.util.Arrays;

/**
 * 环形队列
 */
public class CircularQueue<E> implements Deque<E> {
    /**
     * 读取元素时，front移动，front++
     */
    private int front;
    /**
     * 放入元素时，tail移动，tail++
     */
    private int tail;
    /**
     * 数组
     */
    transient Object[] elementData;
    /**
     * 容量
     */
    private int capacity;
    /**
     * 实际元素个数
     */
    private int size;

    /**
     * 构造方法
     * @param capacity
     */
    public CircularQueue(int capacity) {
        this.capacity = capacity;
        elementData = new Object[capacity];
        front = 0;
        tail = 0;
    }

    /**
     * 添加元素
     * @param e
     */
    @Override
    public void push(E e) {
        if (isFull()) {
            throw new RuntimeException("队列满，无法加入!");
        }
        /**
         * 取模 获取数组下标
         */
        tail = tail % capacity;
        //加入元素
        elementData[tail] = e;
        tail++;
        size++;
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空！");
        }
        front = front % capacity;
        E e = (E) elementData[front];
        front++;
        size--;
        return e;
    }

    @Override
    public boolean isFull() {
        return size == capacity;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void showDequeData() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = front; i < front + size; i++) {
            sb.append(elementData[i % capacity]);
            sb.append(",");
        }
        if (!sb.toString().equals("[")) {
            sb.deleteCharAt(sb.length() - 1);
        }
        sb.append("]");
        System.out.println(sb.toString());

    }


    public static void main(String[] args) {
        CircularQueue<String> circularQueue = new CircularQueue<>(5);
        circularQueue.push("1");
        circularQueue.push("2");
        circularQueue.push("3");
        circularQueue.push("4");
        circularQueue.push("5");
        circularQueue.showDequeData();
        circularQueue.pop();
        circularQueue.showDequeData();
        circularQueue.pop();
        circularQueue.showDequeData();
        circularQueue.pop();
        circularQueue.showDequeData();
        circularQueue.pop();
        circularQueue.showDequeData();
        circularQueue.pop();
        circularQueue.showDequeData();
    }

}
